<template>
  <n-data-table
    ref="tableRef"
    :checked-row-keys="checkedKeys"
    :columns="columnsComp"
    :data="tableData"
    :loading="loading"
    :remote="remote"
    :pagination="paging"
    :single-line="singleLine"
    :size="size"
    :striped="striped"
    :row-key="rowKey"
    :max-height="maxHeight"
    :min-height="minHeight"
    :scroll-x="scrollX || columns.reduce((pre, cur) => pre + (cur.width as number), 0)"
    @update:checked-row-keys="(keys) => emits('update:checkedKeys', keys)"
    @update:page="(page) => onUpdatePage({ page })"
    @update:page-size="(pageSize) => onUpdatePage({ pageSize })"
  ></n-data-table>
</template>

<script lang="tsx" setup>
import type {
  DataTableProps,
  DataTableEmits,
  ReqParams,
  RespPage,
} from "./types";
import { isArray, cloneDeep } from "@/utils";
import { DataTableBaseColumn, NSpace } from "naive-ui";
import TooltipIcon from "@/components/common/tooltip-icon.vue";
import EditIcon from "~icons/ant-design/form-outlined";

const props = withDefaults(defineProps<DataTableProps>(), {
  striped: true,
  singleLine: false,
  checkedKeys: () => [],
  pagination: () => ({
    page: 1,
    pageSize: 10,
    showSizePicker: true,
    pageSizes: [5, 10, 15],
  }),
});
const emits = defineEmits<DataTableEmits>();

const columnsComp = computed(() => {
  const colums = cloneDeep(props.columns);
  // 渲染表头，titleRender优先级比canEdit高
  for (const column of colums) {
    if (column.titleRender) {
      (column as DataTableBaseColumn).title = column.titleRender;
    } else if (column.canEdit) {
      const title = column.title;
      (column as DataTableBaseColumn).title = () => (
        <NSpace align="center">
          {title}
          <TooltipIcon tip="此列可编辑" size={14} color="#444">
            {{ default: () => <EditIcon /> }}
          </TooltipIcon>
        </NSpace>
      );
    }
  }
  return colums;
});

const tableRef = ref();
const loading = ref(false);
const tableData = ref<any[]>([]);

let paging = ref({
  ...props.pagination,
  showSizePicker: !!props.pagination?.pageSizes?.length,
});

const onUpdatePage = ({ page, pageSize }: ReqParams) => {
  if (page) paging.value.page = page;
  if (pageSize) paging.value.pageSize = pageSize;
  if (props.remote) getData();
};

const getData = async () => {
  loading.value = true;
  try {
    const reqParams = {
      page: props.pagination?.page,
      pageSize: props.pagination?.pageSize,
    };
    let resp = await props.request(reqParams);
    if (!resp) resp = { records: [], totalRow: 0 };
    if (isArray(resp)) {
      resp = resp as any[];
      tableData.value = resp;
      props.pagination!.itemCount = resp.length;
    } else {
      resp = resp as RespPage;
      tableData.value = resp.records;
      props.pagination!.itemCount = resp.totalRow;
    }
    emits("update:data", tableData.value);
  } finally {
    loading.value = false;
  }
};

getData();
defineExpose({ getData });
</script>
